package soccerscope.view.layer;

import java.awt.event.ActionEvent;
import java.util.Iterator;
import java.util.Vector;

import javax.swing.AbstractAction;
import javax.swing.JCheckBox;
import javax.swing.JCheckBoxMenuItem;
import javax.swing.JToggleButton;

/**
 * Represents a boolean value which can be changed with a JCheckBox and a
 * JCheckBoxMenuItem.
 * 
 * @author benjaboe
 * 
 */
public class LayerBoolean
    extends AbstractAction {

  private static final long            serialVersionUID = -1548134224894699360L;

  /** The value of this bool. */
  private boolean                      value;

  /** the checkbox for this value. */
  private JCheckBox                    checkBox;

  /** the menuItem for this value. */
  private JCheckBoxMenuItem            menuItem;

  /** the toggle button for this value. */
  private JToggleButton                toggleButton;

  /** The observers of this bool. */
  private Vector<LayerBooleanObserver> observers;

  /** flag whether the boolean value is changing or not. */
  private boolean                      isChanging;

  /**
   * Creates a new boolean with Checkbox and MenuItem.
   * 
   * @param name
   *          the name of the boolean.
   * @param initalValue
   *          the inital value.
   */
  public LayerBoolean(
      String name,
      boolean initalValue) {

    super(name);
    this.value = initalValue;
    this.observers = new Vector<LayerBooleanObserver>();
    this.checkBox = new JCheckBox(name, this.value);
    this.checkBox.addActionListener(this);
    this.menuItem = new JCheckBoxMenuItem(name, this.value);
    this.menuItem.addActionListener(this);
    this.toggleButton = new JToggleButton(name, this.value);
    this.toggleButton.addActionListener(this);
  }

  /**
   * if the value should change.
   */
  public void actionPerformed(ActionEvent e) {

    this.setSelected(!this.value);
  }

  /**
   * returns the value.
   * 
   * @return the value.
   */
  public boolean getValue() {

    return this.value;
  }

  /**
   * Changes the selection state.
   * 
   * @param newValue
   *          new selection state - the new value
   */
  public void setSelected(boolean newValue) {

    this.value = newValue;
    this.checkBox.setSelected(this.value);
    this.menuItem.setSelected(this.value);
    this.toggleButton.setSelected(this.value);

    if (this.isChanging) {
      return;
    }
    this.isChanging = true;
    Iterator<LayerBooleanObserver> it = this.observers.iterator();
    while (it.hasNext()) {
      it.next().boolChanged();
    }
    this.isChanging = false;
  }

  /**
   * return the checkBox.
   * 
   * @return the checkBox
   */
  public JCheckBox getCheckBox() {

    return this.checkBox;
  }

  /**
   * returns the menu item.
   * 
   * @return the menu item
   */
  public JCheckBoxMenuItem getMenuItem() {

    return this.menuItem;
  }

  /**
   * Returns the toggle button.
   * 
   * @return the toggle button
   */
  public JToggleButton getToggleButton() {

    return this.toggleButton;
  }

  /**
   * Adds a observer to the layerBoolean.
   * 
   * @param observer
   *          the new observer.
   */
  public void addObserver(LayerBooleanObserver observer) {

    if (!this.observers.contains(observer)) {
      this.observers.add(observer);
    }
  }

  /**
   * Removes a observer from this layerBoolean.
   * 
   * @param observer
   *          the observer to remove
   */
  public void removeObserver(LayerBooleanObserver observer) {

    this.observers.remove(observer);
  }
}
